const { Product } = require('../models')
const { Op } = require('sequelize')
const logger = require('../utils/logger')

class ProductService {
  /**
   * 获取商品列表
   * @param {Object} options - 查询选项
   * @returns {Promise<Object>} 商品列表和分页信息
   */
  async getProducts(options = {}) {
    try {
      const {
        category,
        type,
        status = 1,
        isHot,
        isNew,
        search,
        page = 1,
        limit = 20,
        sortBy = 'sort_order',
        sortOrder = 'DESC'
      } = options

      // 构建查询条件
      const where = { status }
      
      if (category) {
        where.category = category
      }
      
      if (type) {
        where.type = type
      }
      
      if (isHot !== undefined) {
        where.is_hot = isHot
      }
      
      if (isNew !== undefined) {
        where.is_new = isNew
      }
      
      if (search) {
        where[Op.or] = [
          { name: { [Op.like]: `%${search}%` } },
          { description: { [Op.like]: `%${search}%` } }
        ]
      }

      // 计算偏移量
      const offset = (page - 1) * limit

      // 查询商品
      const result = await Product.findAndCountAll({
        where,
        limit: parseInt(limit),
        offset,
        order: [[sortBy, sortOrder.toUpperCase()]],
        attributes: {
          exclude: ['created_at', 'updated_at']
        }
      })

      return {
        products: result.rows,
        pagination: {
          total: result.count,
          page: parseInt(page),
          limit: parseInt(limit),
          pages: Math.ceil(result.count / limit)
        }
      }
    } catch (error) {
      logger.error('获取商品列表失败:', error)
      throw new Error('获取商品列表失败')
    }
  }

  /**
   * 根据ID获取商品详情
   * @param {number} productId - 商品ID
   * @returns {Promise<Object>} 商品详情
   */
  async getProductById(productId) {
    try {
      const product = await Product.findOne({
        where: { 
          id: productId,
          status: 1
        }
      })

      if (!product) {
        // 如果数据库中没有找到商品，尝试返回模拟数据
        const mockProduct = this.getMockProductById(productId)
        if (mockProduct) {
          return mockProduct
        }
        throw new Error('商品不存在或已下架')
      }

      return product
    } catch (error) {
      // 如果是数据库连接错误，尝试返回模拟数据
      if (error.name === 'SequelizeConnectionError' || error.name === 'SequelizeConnectionRefusedError') {
        logger.warn('数据库连接失败，使用模拟数据:', error.message)
        const mockProduct = this.getMockProductById(productId)
        if (mockProduct) {
          return mockProduct
        }
      }
      logger.error('获取商品详情失败:', error)
      throw error
    }
  }

  /**
   * 创建商品
   * @param {Object} productData - 商品数据
   * @returns {Promise<Object>} 创建的商品
   */
  async createProduct(productData) {
    try {
      const product = await Product.create(productData)
      logger.info(`商品创建成功: ${product.id}`)
      return product
    } catch (error) {
      logger.error('创建商品失败:', error)
      throw new Error('创建商品失败')
    }
  }

  /**
   * 更新商品
   * @param {number} productId - 商品ID
   * @param {Object} updateData - 更新数据
   * @returns {Promise<Object>} 更新后的商品
   */
  async updateProduct(productId, updateData) {
    try {
      const product = await Product.findByPk(productId)
      if (!product) {
        throw new Error('商品不存在')
      }

      await product.update(updateData)
      logger.info(`商品更新成功: ${productId}`)
      return product
    } catch (error) {
      logger.error('更新商品失败:', error)
      throw error
    }
  }

  /**
   * 删除商品（软删除）
   * @param {number} productId - 商品ID
   * @returns {Promise<boolean>} 删除结果
   */
  async deleteProduct(productId) {
    try {
      const product = await Product.findByPk(productId)
      if (!product) {
        throw new Error('商品不存在')
      }

      await product.update({ status: 0 })
      logger.info(`商品删除成功: ${productId}`)
      return true
    } catch (error) {
      logger.error('删除商品失败:', error)
      throw error
    }
  }

  /**
   * 更新商品库存
   * @param {number} productId - 商品ID
   * @param {number} quantity - 库存变化量（正数增加，负数减少）
   * @returns {Promise<Object>} 更新后的商品
   */
  async updateStock(productId, quantity) {
    try {
      const product = await Product.findByPk(productId)
      if (!product) {
        throw new Error('商品不存在')
      }

      const newStock = product.stock_quantity + quantity
      if (newStock < 0) {
        throw new Error('库存不足')
      }

      await product.update({ stock_quantity: newStock })
      logger.info(`商品库存更新: ${productId}, 变化: ${quantity}, 当前库存: ${newStock}`)
      return product
    } catch (error) {
      logger.error('更新商品库存失败:', error)
      throw error
    }
  }

  /**
   * 批量更新商品库存
   * @param {Array} stockUpdates - 库存更新数组 [{productId, quantity}]
   * @returns {Promise<boolean>} 更新结果
   */
  async batchUpdateStock(stockUpdates) {
    try {
      for (const update of stockUpdates) {
        await this.updateStock(update.productId, update.quantity)
      }
      return true
    } catch (error) {
      logger.error('批量更新库存失败:', error)
      throw error
    }
  }

  /**
   * 获取商品分类列表
   * @returns {Promise<Array>} 分类列表
   */
  async getCategories() {
    try {
      // 返回模拟的分类数据，因为当前没有独立的分类表
      const categories = [
        {
          id: 1,
          name: '打印服务',
          type: 'print',
          description: '各种文档打印服务',
          icon: '/static/icons/print.png'
        },
        {
          id: 2,
          name: '复印服务',
          type: 'copy',
          description: '文档复印服务',
          icon: '/static/icons/copy.png'
        },
        {
          id: 3,
          name: '装订服务',
          type: 'binding',
          description: '文档装订服务',
          icon: '/static/icons/binding.png'
        },
        {
          id: 4,
          name: '扫描服务',
          type: 'scan',
          description: '文档扫描服务',
          icon: '/static/icons/scan.png'
        },
        {
          id: 5,
          name: '办公用品',
          type: 'supplies',
          description: '各种办公用品',
          icon: '/static/icons/supplies.png'
        }
      ]

      return categories
    } catch (error) {
      logger.error('获取商品分类失败:', error)
      throw new Error('获取商品分类失败')
    }
  }

  /**
   * 获取热门商品
   * @param {number} limit - 限制数量
   * @returns {Promise<Array>} 热门商品列表
   */
  async getHotProducts(limit = 10) {
    try {
      const products = await Product.findAll({
        where: {
          status: 1,
          is_hot: true
        },
        limit,
        order: [['sort_order', 'DESC'], ['created_at', 'DESC']],
        attributes: {
          exclude: ['created_at', 'updated_at']
        }
      })

      return products
    } catch (error) {
      logger.error('获取热门商品失败:', error)
      throw new Error('获取热门商品失败')
    }
  }

  /**
   * 获取新品商品
   * @param {number} limit - 限制数量
   * @returns {Promise<Array>} 新品商品列表
   */
  async getNewProducts(limit = 10) {
    try {
      const products = await Product.findAll({
        where: {
          status: 1,
          is_new: true
        },
        limit,
        order: [['created_at', 'DESC']],
        attributes: {
          exclude: ['created_at', 'updated_at']
        }
      })

      return products
    } catch (error) {
      logger.error('获取新品商品失败:', error)
      throw new Error('获取新品商品失败')
    }
  }

  /**
   * 检查商品库存
   * @param {number} productId - 商品ID
   * @param {number} quantity - 需要的数量
   * @returns {Promise<boolean>} 库存是否充足
   */
  async checkStock(productId, quantity) {
    try {
      const product = await Product.findByPk(productId)
      if (!product) {
        throw new Error('商品不存在')
      }

      return product.stock_quantity >= quantity
    } catch (error) {
      logger.error('检查商品库存失败:', error)
      throw error
    }
  }

  /**
   * 获取模拟商品数据（用于数据库不可用时）
   * @param {number} productId - 商品ID
   * @returns {Object|null} 模拟商品数据
   */
  getMockProductById(productId) {
    const mockProducts = {
      1: {
        id: 1,
        name: '专业彩色打印服务',
        description: '高质量彩色打印，适用于各类文档、图片、海报等。使用进口墨水，色彩鲜艳持久。支持多种纸张类型，满足不同需求。',
        original_price: 20.00,
        points_price: 100.00,
        image_url: '/static/icons/default-product.svg',
        category: 'print',
        type: 'color_print',
        paper_size: 'A4',
        paper_type: '铜版纸120g',
        color_type: 'color',
        stock_quantity: 999,
        stock_warning: 100,
        sales_count: 0,
        is_hot: true,
        is_new: false,
        status: 1,
        sort_order: 100,
        specifications: {
          paper_type: 'coated',
          paper_weight: '120',
          paper_size: 'A4',
          color_mode: 'color',
          sides: 'double',
          dpi: '1200',
          finish: 'glossy'
        },
        created_at: new Date(),
        updated_at: new Date()
      },
      2: {
        id: 2,
        name: '黑白文档打印',
        description: '经济实惠的黑白打印服务，适合日常文档、作业、报告等。清晰度高，成本低廉。',
        original_price: 10.00,
        points_price: 50.00,
        image_url: '/static/icons/default-product.svg',
        category: 'print',
        type: 'bw_print',
        paper_size: 'A4',
        paper_type: '普通纸80g',
        color_type: 'bw',
        stock_quantity: 999,
        stock_warning: 100,
        sales_count: 0,
        is_hot: false,
        is_new: false,
        status: 1,
        sort_order: 90,
        specifications: {
          paper_type: 'normal',
          paper_weight: '80',
          paper_size: 'A4',
          color_mode: 'black',
          sides: 'single',
          dpi: '600',
          finish: 'matte'
        },
        created_at: new Date(),
        updated_at: new Date()
      },
      3: {
        id: 3,
        name: '螺旋装订服务',
        description: '专业螺旋装订，可180度平摊，适合笔记本、日历、教材等装订。牢固耐用，美观实用。',
        original_price: 15.00,
        points_price: 80.00,
        image_url: '/static/icons/default-product.svg',
        category: 'service',
        type: 'binding',
        paper_size: null,
        paper_type: null,
        color_type: null,
        stock_quantity: 500,
        stock_warning: 50,
        sales_count: 0,
        is_hot: false,
        is_new: true,
        status: 1,
        sort_order: 80,
        specifications: {
          binding_type: 'spiral',
          max_pages: 120,
          cover_options: '透明封面+硬卡纸封底',
          colors: '黑色、白色、蓝色可选',
          material: '优质塑料螺旋圈'
        },
        created_at: new Date(),
        updated_at: new Date()
      }
    }

    return mockProducts[productId] || null
  }
}

module.exports = new ProductService()